
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/miscdevice.h> 
#include <linux/platform_device.h> /*platform 驱动框架头文件*/



/* 实现系统调用接口：open()，在platform中保持不变 */
static int aml_misc_open(struct inode *inode, struct file *file)
{
	pr_info("aml_misc_open()-> platform is called.\n");
	return 0;
}


/* 实现系统调用接口：close()，在platform中保持不变  */
static int aml_misc_close(struct inode *inode, struct file *file)
{
	pr_info("aml_misc_close()-> platform is called.\n");
	return 0;
}


/* 实现系统调用接口：ioctl()，在platform中保持不变  */
static long aml_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	pr_info("aml_misc_ioctl()-> platform is called. cmd = %d, arg = %ld\n", cmd, arg);
	return 0;
}

static const struct file_operations aml_misc_fops = {
	.owner = THIS_MODULE,  /* 固定搭配 */
	.open = aml_misc_open, /* 提供open()， fopen()系统调用 */
	.release = aml_misc_close, /* 提供close()， fclose()系统调用 */
	.unlocked_ioctl = aml_misc_ioctl, /* 提供ioctl()系统调用 */
};

/* 声明 struct miscdevice 结构体变量，并赋值*/
static struct miscdevice aml_misc_device = {
		.minor = MISC_DYNAMIC_MINOR,  /* 优点：misc设备已由misc框架提供了主设备号，其余设备通过此设定，自动分配一个次设备号*/
		.name = "aml_plat_misc_dev",  /* 将创建/dev/aml_plat_misc_dev    以及 /sys/class/misc/aml_plat_misc_dev */
		.fops = &aml_misc_fops, 
};


//static int __init aml_misc_init(void)
//驱动在DTS中探测到相兼容的设备，将自动运行probe初始化，并创建设备，相比misc驱动，只是更换函数接口，实现大体还是一样
static int __init my_probe(struct platform_device *pdev)

{
	int ret;
	pr_info("aml_misc_init-> my_probe\n");

	/* 将miscdevice对象注册进内核 */
	ret = misc_register(&aml_misc_device);

	if (ret != 0) {
		pr_err("Failded: misc_register aml_misc_dev-> my_probe\n");
		return ret;
	}

	pr_info("init alloc aml_misc_dev's minor[%i]-> my_probe\n",aml_misc_device.minor);
	return 0;
}


//static void __exit aml_misc_exit(void)
//同样的，用platform的remove替代之前的exit，相比misc驱动，只是更换函数接口，实现大体还是一样
static int __exit my_remove(struct platform_device *pdev)
{
	pr_info("aml_misc_exit -> my_remove\n");

	/* 注销miscdevice对象 */
	misc_deregister(&aml_misc_device);
	return 0;
}


/*
 * (1) 新增of_device_id，用于与DTS中静态描述的设备做匹配
 * (2) 需要在DTS中添加具备 .compatible 属性的节点，否则无法触发 probe()函数的执行
*/
static const struct of_device_id my_of_ids[] = {
	{ .compatible = "szhou,aml_plat_dev"},
	{},
};


//导出my_of_ids符号，供内核使用
MODULE_DEVICE_TABLE(of, my_of_ids);

/* 定义platform_driver对象，用于注册到内核Platform总线中 */
static struct platform_driver my_platform_driver = {
	.probe = my_probe,
	.remove = my_remove,
	.driver = {
		.name = "aml_plat_dev",
		.of_match_table = my_of_ids,
		.owner = THIS_MODULE,
	}
};

/* 注册我们的platform驱动 */
module_platform_driver(my_platform_driver);


/*下面两句可以省略了，驱动在DTS中探测到相兼容的设备，将自动运行probe初始化，并创建设备*/
//module_init(aml_misc_init);
//module_exit(aml_misc_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("szhou <66176468@qq.com>");
MODULE_DESCRIPTION("simple say[3]: misc device driver");



